\indent La funcionalidad de este filtro consiste en combinar la imagen original con una imagen de ondas, dando tonos mas oscuros y mas claros en forma de onda. Estas se generan de manera repetida a lo largo de los ejes x e y.\\
\indent La idea de la implementaci\'on es dividir el algoritmo en 3 niveles: \\
\begin{itemize}
    \item ciclo principal: recorrer cada pixel de la imagen fuente, procesarlos de a 4 y guardarlos en destino. La idea por la cual solo procesamos de a 4 pixels por iteraci\'on se debe a que vamos a necesitar usar floats para los c\'alculos y en cada registro xmm entran 4 de estos.
    \item funci\'on $prof_{i,j}$ e $I_{dest}$: calcular el valor de las funciones para cada uno de los 4 pixels, usando $sin\_taylor$ para completar los c\'alculos
    \item $sin\_taylor$: implementación del algoritmo para 4 \'indices de recorrido de la imagen
  \end{itemize}
\indent



\subsubsection{Carga de datos}

\indent El algoritmo comienza tomando los 3 par\'ametros $x\_scale$, $y\_scale$ y $g\_scale$ pasados como par\'ametros y los guarda en variables del mismo nombre, puesto que m\'as adelante vamos a necesitar todos los registros xmm para los c\'alculos de floats.\\
Vamos a tener un contador de filas ($r13$), columnas ($r12$), cantidad de filas ($r15$) y necesitamos saber el ancho de cada fila ($r14$), para no procesar el padding.\\
\indent El ciclo principal se divide a su vez en dos ciclos, el externo que va incrementando los \'indices de a 16 bytes y el interno que procesa de a 4 pixeles. La raz\'on para procesar solo 4 pixeles en simultaneo es, como bien explicamos antes, debido a la necesidad de trabajar con floats de 4 bytes cada uno.\\
\indent Cada iteraci\'on del ciclo externo
\begin{itemize}
\item Se asigna $r12$ (columna actual) a $r11$
\item Se suma 16 a $r11$
\item Se compara $r11$ con $r14$ (ancho de la fila) con la intenci\'on de ver si los pr\'oximos 16 bytes se van a pasar del l\'imite de ancho de la fila
\item En caso que nos pasemos ($r11 > r14$) y como queremos procesar de a 16 bytes, ubicamos la columna actual en (ancho de la columna - 16)
\item Sabiendo que los pr\'oximos 16 bytes pertenecen a la fila actual, se ejecuta el ciclo interno
\begin{itemize}
	\item Inicializamos el contador de iteraciones $rcx$ a 4
	\item Guardamos las posiciones actuales dentro de la matriz en las variables \verb+pos_i_actual+ y \verb+pos_j_actual+. La raz\'on de guardar en variables y no en registros, es que no nos alcanzaban los registros para estos datos.
	\item Obtenemos los 4 bytes de la imagen fuente ($[rdi + r12]$) y los guardamos en $xmm0$. La raz\'on por la que usamos $xmm0$ es porque necesitamos pasarlo como par\'ametro a una funci\'on.
	\item Previo a llamar a la funci\'on \textit{calcularValorDst} , necesitamos guardar el contador de iteraciones del ciclo interno $rcx$ en la pila para no pisarlo (puesto que el registro $rcx$ no pertenece al standard de pasaje de par\'ametros y su valor puede (y lo har\'a) cambiar.
	\item La funci\'on devolver\'a los 4 pixels procesados en el registro $xmm0$, de modo que lo guardamos en el buffer correspondiente a la imagen resultado $[rsi + r12]$.
\end{itemize}
\item Al terminar el ciclo interno, se suma 16 a $r12$ (columna actual) y se chequea si se termin\'o la fila \textit{cmp r12, r14}.
\item En caso que no, se vuelve al primer punto
\item En caso que hayamos terminado la fila, se asigna 0 a $r12$ (columna actual), se incrementa en 1 a $r13$ (filas procesadas) y se incrementan los punteros a la imagen original ($rdi$) y destino ($rsi$) para que apunten a la siguiente fila.
\item Si $r13$ es mayor o igual a $r15$ (cantidad de filas), se termino de procesar la imagen.
\item En caso que no, se salta al primer punto
\end{itemize}
\indent Notar que no es necesario hacer ningun recalculo en los \'indices para guardar los pixels procesados puesto que cada pixel puede ser procesado independientemente del resto y es guardado en exactamente el mismo lugar que la posici\'on que ten\'ia en la imagen fuente (caso contrario es por ejemplo el filtro recortar).


\subsubsection{Ciclo Principal}

\indent Con los datos cargados en los respectivos registros, vamos a mostrar dos iteraciones del filtro. Una de ellas ser\'a la del ciclo interno de la funci\'on princial. Puesto que los resultados se van calculando en funciones auxiliares, nos pareci\'o apropiado tambi\'en mostrar una iteracion de la principal de esas funciones auxiliares, para facilitar la comprensi\'on del algoritmo final.
\begin{itemize}
\item Comenzamos cargando 4 pixels de la imagen original (tercer paso del ciclo interno antes descripto) mediante $movd xmm0, [rdi + r12]$. El contenido del registro $xmm0$ ser\'a:\\
\begin{center}
\xmmxByteHigh{$0$}{$0$}{$0$}{$0$}{$0$}{$0$}{$0$}{$0$}\xmmxByteLow{$P_{1}$}{$P_{2}$}{$P_{3}$}{$P_{4}$}{$0$}{$0$}{$0$}{$0$}
\end{center}
\indent que fu\'e cargado de $[rdi + r12]$:
\begin{center}
\xmmxByteHigh{$P_8$}{$P_9$}{$P_{10}$}{$P_{11}$}{$P_{12}$}{$P_{13}$}{$P_{14}$}{$P_{15}$}\xmmxByteLow{$P_0$}{$P_1$}{$P_2$}{$P_3$}{$P_4$}{$P_5$}{$P_6$}{$P_7$}
\end{center}
\item Se llama a la funci\'on $calcularValorDst$ pasando como par\'ametro el registro $xmm0$
\item Al finalizar la ejecuci\'on de la funci\'on, se espera el siguiente contenido en $xmm0$
	\begin{center}
	\xmmxByteHigh{$0$}{$0$}{$0$}{$0$}{$0$}{$0$}{$0$}{$0$}\xmmxByteLow{$PP_{1}$}{$PP_{2}$}{$PP_{3}$}{$PP_{4}$}{$0$}{$0$}{$0$}{$0$}
	\end{center}
\indent haciendo PP referencia al correspondiente pixel procesado ($PP_i$ = Pixel Procesado n\'umero i)
\item Se guardan los pixels procesados en el buffer correspondiente a la imagen final, ubicada en $[rsi + r12]$
	\begin{center}
	\xmmxByteHigh{$*$}{$*$}{$*$}{$*$}{$*$}{$*$}{$*$}{$*$}\xmmxByteLow{$PP_{1}$}{$PP_{2}$}{$PP_{3}$}{$PP_{4}$}{$*$}{$*$}{$*$}{$*$}
	\end{center}
\indent los bytes referenciados con $*$ son aquellos para los cuales no sabemos su valor pu\'es a\'un no han sido procesados
\item Se suma 4 al contador de columna actual $r12$
\item Se loopea segun el valor del contador de iteraciones $rcx$.
\end{itemize}
\indent A continuaci\'on damos una descripci\'on de alto nivel de la subrutina principal del algoritmo ($calcularValorDst$)
\begin{itemize}
\item Como vamos a trabajar con valores de tipo float y nosotros cargamos bytes antes de llamar a esta funci\'on, tenemos que hacer un unpack de esos bytes a 4 bytes usando la instrucci\'on $punpcklbw$ y $punpcklwd$. De esta forma, nos queda el registro $xmm7$
	\begin{center}
	\xmmxDWord{$F_{1}$}{$F_{2}$}{$F_{3}$}{$F_{4}$}
	\end{center}
\indent siendo F los pixels transformados a 4 bytes (un float de single precision)
\item Asignamos 8 a $xmm6$ y lo replicamos a sus 4 floats, quedando:
	\begin{center}
	\xmmxDWord{$8$}{$8$}{$8$}{$8$}
	\end{center}
\item Asignamos $i$ (columna actual) a $xmm5$ y lo replicamos a sus 4 floats, quedando:
	\begin{center}
	\xmmxDWord{$i$}{$i$}{$i$}{$i$}
	\end{center}
\item Dividimos $xmm5$ por $xmm6$ quedando:
\begin{center}
\xmmxDWord{$i/8$}{$i/8$}{$i/8$}{$i/8$}
\end{center}
\item Se llama a $sin\_taylor$ pasando como par\'ametro el resultado de la divisi\'on anterior, quedando $xmm5$ :
	\begin{center}
	\xmmxDWord{$ST_{i/8}$}{$ST_{i/8}$}{$ST_{i/8}$}{$ST_{i/8}$}
	\end{center}
\indent siendo ST el resultado de llamar a $sin\_taylor$.
\item Se multiplica el resultado anterior por $x\_scale$ y se guarda $xmm5$ en la variable $tmp\_calc$. Dicho resultado representa el operando izquierdo del numerador de la funci\'on $prof_{i,j}$.
\item De manera an\'aloga se calcula el operando derecho pero en esta ocasi\'on se usa $j$ en vez de $i$ y se multiplica por el valor de $y\_scale$. El resultado se guarda en $xmm4$
\item Se suma $xmm5$ (operando izquierdo) con $xmm4$ (operando derecho)
\item Asignamos 2 a $xmm4$ y lo replicamos a sus 4 floats, quedando:
	\begin{center}
	\xmmxDWord{$2$}{$2$}{$2$}{$2$}
	\end{center}
\item Se divide $xmm5$ (resultado del numerador) por $xmm4$ (constante 2), quedando asi :
	\begin{center}
	\xmmxDWord{$Pr_{1}$}{$Pr_{1}$}{$Pr_{1}$}{$Pr_{1}$}
	\end{center}
\indent siendo $Pr_{k}$ el resultado de la funci\'on $prof_{i,j}$ con $k \in {1,2,3,4}$
\item Se asigna $g\_scale$ a $xmm4$ y se multiplica por el resultado anterior ($xmm5$)
	\begin{center}
	\xmmxDWord{$GPr_{1}$}{$GPr_{1}$}{$GPr_{1}$}{$GPr_{1}$}
	\end{center}
\indent con $GPr_{i}$ el resultado de multiplicar $g\_scale$ por cada float del resultado anterior
\item Por \'ultimo, el \'ultimo resultado (en $xmm5$) se suma (saturando) a los respectivos pixels de la imagen original (se representan con $I_{src}$ en la f\'ormula del enunciado
\item con esa \'ultima cuenta se da por terminada la iteraci\'on para procesar los 4 pixels.
\end{itemize}






